<?php
namespace App\GraphQL\Mutations\DeviceOrder;

use App\Models\DeviceOrder;
use App\Models\FactoryStatistical;
use GraphQL\Type\Definition\ResolveInfo;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Kra8\Snowflake\Snowflake;
use Nuwave\Lighthouse\Support\Contracts\GraphQLContext;

class Delivery
{

    /**
     * Return a value for the field.
     *
     * @param null $rootValue
     *            Usually contains the result returned from the parent field. In this case, it is always `null`.
     * @param mixed[] $args
     *            The arguments that were passed into the field.
     * @param \Nuwave\Lighthouse\Support\Contracts\GraphQLContext $context
     *            Arbitrary data that is shared between all fields of a single query.
     * @param \GraphQL\Type\Definition\ResolveInfo $resolveInfo
     *            Information about the query itself, such as the execution state, the field name, path to the field from the root, and more.
     * @return mixed
     */
    public function __invoke($rootValue, array $args, GraphQLContext $context, ResolveInfo $resolveInfo)
    {
        DB::transaction(function () use ($args) {
            $authUser = auth()->user();
            $data = $args['input'];
            $id = $args['id'];
            $deviceOrder = $this->validate($id, $data);
            $factory = $deviceOrder->factory;
            $data['delivery_address_detail'] = $factory->address_detail;
            $data['delivery_address'] = $factory->address;
            $data['factory_time'] = Carbon::now();
            $data['status'] = 'WAIT_RECEIPT';
            $data['delivery_user_id'] = $authUser->id;
            $deviceOrder->update($data);
            // 将厂家下该订单设备移动至正式设备表
            $factoryDevices = $deviceOrder->factory_devices;
            $devices = $factoryDevices->map(function ($item) use (&$deviceOrder) {
                $temp = [
                    'id' => resolve(Snowflake::class)->next(),
                    'style' => $deviceOrder->style,
                    'status' => 'SHIPPED',
                    'mac_address' => $item['mac_address'],
                    'unique_id' => $item['unique_id'],
                    'connection_password' => $item['connection_password'],
                    'user_id' => $item['user_id'],
                    'device_order_id' => $item['device_order_id'],
                    'province' => $deviceOrder->author->province,
                    'city' => $deviceOrder->author->city,
                    'area' => $deviceOrder->author->area,
                    'device_group_id' => $deviceOrder->device_group_id,
                    'created_at' => Carbon::now(),
                    'updated_at' => Carbon::now()
                ];
                return $temp;
            });
            $deviceOrder->factory_devices()->update([
                'status' => 'READONLY'
            ]);
            if ($devices->count() > 0) {
                DB::table('devices')->insert($devices->toArray());
            }
            $logs = $devices->map(function ($item) {
                $temp = [
                    'id' => resolve(Snowflake::class)->next(),
                    'level' => 'BLUE',
                    'user_id' => $item['user_id'],
                    'device_id' => $item['id'],
                    'content' => '出厂',
                    'created_at' => Carbon::now(),
                    'updated_at' => Carbon::now()
                ];
                return $temp;
            });
            DB::table('device_logs')->insert($logs->toArray());
            // 更新厂家统计
            // 今日处理订单数更新
            $factoryStatistical = FactoryStatistical::firstOrCreate(['user_id'=>$deviceOrder->factory_user_id]);
            $lastUpdatedDate = new Carbon($factoryStatistical->updated_at);
            // 判断最后统计时间是否是今天
            if($lastUpdatedDate->isToday()){
                $factoryStatistical->increment('today_handle_order_count');
            }else{
                $factoryStatistical->update(['today_handle_order_count'=>1]);
            }
            $factoryStatistical->increment('total_ship_device',$devices->count());
        });
        return [
            'status' => '200',
            'message' => '发货成功'
        ];
    }

    public function validate($id, $data)
    {
        $rules = [
            'ship_voucher' => [
                'required'
            ]
        ];
        $messages = [
            'ship_voucher.required' => '发货凭证不能为空'
        ];
        $validate = Validator::make($data, $rules, $messages);
        if ($validate->fails()) {
            throw new \InvalidArgumentException($validate->messages()->first());
        }
        $old = DeviceOrder::find($id);
        if (! $old) {
            throw new \Exception('订单不存在!');
        }
        if ($old->status === 'WAIT_RECEIPT') {
            throw new \Exception('订单已经发货,无法操作!');
        }
        if ($old->status !== 'WAIT_DELIVERY') {
            throw new \Exception('订单未支付,无法操作!');
        }
        return $old;
    }
}
